#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "alloc-testing.h"

void test_malloc_free(void) {
    void *ptr = alloc_test_malloc(100);
    assert(ptr != NULL);
    assert(alloc_test_get_allocated() == 100);

    alloc_test_free(ptr);
    assert(alloc_test_get_allocated() == 0);
}

void test_realloc(void) {
    void *ptr = alloc_test_malloc(100);
    assert(ptr != NULL);
    assert(alloc_test_get_allocated() == 100);

    void *new_ptr = alloc_test_realloc(ptr, 200);
    assert(new_ptr != NULL);
    assert(alloc_test_get_allocated() == 200);

    alloc_test_free(new_ptr);
    assert(alloc_test_get_allocated() == 0);
}

void test_calloc(void) {
    void *ptr = alloc_test_calloc(10, 10);
    assert(ptr != NULL);
    assert(alloc_test_get_allocated() == 100);

    // Ensure memory is zeroed out
    for (int i = 0; i < 100; ++i) {
        assert(((char *)ptr)[i] == 0);
    }

    alloc_test_free(ptr);
    assert(alloc_test_get_allocated() == 0);
}

void test_strdup(void) {
    const char *str = "Hello, World!";
    char *dup_str = alloc_test_strdup(str);
    assert(dup_str != NULL);
    assert(strcmp(dup_str, str) == 0);
    assert(alloc_test_get_allocated() == strlen(str) + 1);

    alloc_test_free(dup_str);
    assert(alloc_test_get_allocated() == 0);
}

void test_allocation_limit(void) {
    alloc_test_set_limit(2);

    void *ptr1 = alloc_test_malloc(100);
    assert(ptr1 != NULL);
    assert(alloc_test_get_allocated() == 100);

    void *ptr2 = alloc_test_malloc(100);
    assert(ptr2 != NULL);
    assert(alloc_test_get_allocated() == 200);

    void *ptr3 = alloc_test_malloc(100);
    assert(ptr3 == NULL);
    assert(alloc_test_get_allocated() == 200);

    alloc_test_free(ptr1);
    alloc_test_free(ptr2);
    assert(alloc_test_get_allocated() == 0);

    alloc_test_set_limit(-1); // Reset limit
}

int main(void) {
    test_malloc_free();
    test_realloc();
    test_calloc();
    test_strdup();
    test_allocation_limit();

    printf("All tests passed!\n");
    return 0;
}